package com.edu.robot.core.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.edu.robot.core.enums.NotifyMsgEnum;
import com.edu.robot.core.model.APICallback;
import com.edu.robot.core.model.SessionContext;
import com.edu.robot.core.model.ToolResult;
import com.edu.robot.model.R;
import com.edu.robot.model.enums.ResultCodeEnum;
import com.edu.robot.model.error.BizException;
import com.edu.robot.modules.robot.dto.*;
import com.edu.robot.modules.robot.service.CrToolService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @program: KQAIA
 * @description:
 * @author: 无恙
 * @create: 2025-03-23 17:19
 **/

@Component("toolModelProcess")
@Slf4j
public class ToolModelProcess extends AbstractModelInvoke{

	@Autowired
	private CrToolService crToolService;

	@Autowired
	private ChatModelProcess chatModelProcess;

	@Override
	public void buildModel(SessionContext sessionContext) {

		//设置模型参数
		ModelConfigDTO modelConfigDTO = new ModelConfigDTO();
		modelConfigDTO.setModelName("qwen-max");
		sessionContext.setModelConfigDTO(modelConfigDTO);
	}

	@Override
	public void buildPrompt(SessionContext sessionContext) {

		//获取funcall提示词模板
		RobotInfoDTO robot = sessionContext.getRobot();

		RobotConfigDTO robotConfig = robot.getRobotConfig();

		List<String> toolConfigId = robotConfig.getToolConfigId();

		if(CollectionUtil.isEmpty(toolConfigId)){
			throw new BizException(ResultCodeEnum.CONFIG_ERROR,"该机器人没有配置工具！");
		}

		R<String> functionCallTemplate = crToolService.getFunctionCallTemplate(toolConfigId);

		//校验数据，填充到上下文，打印日志
		if(!functionCallTemplate.isSuccess() || functionCallTemplate.getData() == null){
			throw new BizException(ResultCodeEnum.DATABASE_ERROR,"工具提示词模板不存在");
		}

		sessionContext.setPrompt(functionCallTemplate.getData());

		log.info("ToolModelProcess buildPrompt 工具提示词模板:{}",functionCallTemplate.getData());

	}

	@Override
	public String invokeModel(SessionContext sessionContext) {

		String finalAnswer = modelManger.modelInvoke(sessionContext);

		try {
			ToolResult toolResult = JSONUtil.toBean(finalAnswer, ToolResult.class);

			//如果toolResult含有缺失数据，返回前端用户
			if(!Objects.isNull(toolResult.getMissingParams()) && StringUtils.isNotBlank(toolResult.getMissingParams().getQuestion())){
				APICallback callback = sessionContext.getCallback();
				callback.onEvent(NotifyMsgEnum.NORMAL,toolResult.getMissingParams().getQuestion());
				callback.close(toolResult.getMissingParams().getQuestion());
				return toolResult.getMissingParams().getQuestion();
			}

			//获取该机人的工具列表
			R<List<ToolInfoDTO>> toolList = crToolService.getToolList(sessionContext.getRobot().getRobotConfig().getToolConfigId());

			//校验
			if(!toolList.isSuccess() || CollectionUtil.isEmpty(toolList.getData())){
				throw new BizException(ResultCodeEnum.DATABASE_ERROR,"工具列表为空");
			}

			Map<String, String> collect = toolList.getData().stream().collect(Collectors.toMap(ToolInfoDTO::getName, ToolInfoDTO::getId));

			//获取工具名称和参数
			String toolName = toolResult.getTool();
			Map<String, Object> params = toolResult.getParams();

			//获取工具id
			String toolId = collect.get(toolName);

			//if工具id为空,抛异常
			if(Objects.isNull(toolId)){
				throw new BizException(ResultCodeEnum.DATABASE_ERROR,"模型返回结果中未找到对应工具");
			}

			//执行工具
			finalAnswer= crToolService.useTool(toolId, params);

		}catch (Exception e){
			log.info("工具数据解析失败：{}",e.getMessage());
			//获取用户提问，直接走闲聊
			finalAnswer= sessionContext.getQuestion();
		}

		sessionContext.setAgentAnswer(finalAnswer);

		return chatModelProcess.invokeFallback(sessionContext);

	}
}
